<script setup lang="ts">
import Pagination from '@/components/Pagination.vue'
import $mitt from '@/common/emitter'
import { COPY_TEXT_FN } from '@/common/hooks'
import { Utils, Utils_Math } from '@/common/utils.js'
import type { TableHeaderColumnsItemType, TableDataInitType } from '@/components/tableType'

const emit = defineEmits([
	'TABLE_DATA_SELECT_EVENT',
	'TABLE_DATA_VIEW_EVENT', 
	'TABLE_DATA_DETAIL_EVENT',
	'TABLE_DATA_EDIT_EVENT', 
	'TABLE_DATA_ADD_EVENT',
	// 删除/批量删除
	'TABLE_DATA_DELETE_EVENT', 
	// 翻页
	'TABLE_DATA_UPDATE_EVENT', 
])
const vPreventReClick = inject('vPreventReClick')
const vAuth = inject('vAuth')
const { tableHeaderColumns } = defineProps<{
	tableHeaderColumns: TableHeaderColumnsItemType[]
}>()
const tableData = defineModel<TableDataInitType>('tableData', {required: true})
const tableDataValue = tableData.value
const FONTS = 'Helvetica Neue,Helvetica,Arial,Microsoft Yahei,Hiragino Sans GB,Heiti SC,WenQuanYi Micro Hei,sans-serif'
const SWITCH_ON_TEXT = '启用'
const SWITCH_OFF_TEXT = '禁用'
// type TableHeaderColumnsItemType = typeof tableHeaderColumns[0]
type RowType = typeof tableData.value.data[0]
type RowsType = RowType[]
type MainParamsType = {
	selectRows: RowsType
}
const mainParams: MainParamsType = reactive({
	selectRows: []
})

// 表格序列号
const serialIndexFn = (index: number) => (tableData.value.currentPage - 1) * tableData.value.pageSize + index + 1

// 复选框
const handleSelectionChange = (rows: RowsType) => {
	// 存储所有选中的行，批量操作使用
	mainParams.selectRows = rows
	// 先触发TABLE_DATA_SELECT_EVENT，将所有选中的数据select状态初始化为false
	emit('TABLE_DATA_SELECT_EVENT')
	// 设置选中的数据的select状态
	let selected = 0
	rows.forEach(item => {
		item.isSelect = true
		selected++
	})
	// 设置选择数据条数
	tableData.value.selected = selected
}

// 预览
const handleViewFn = (row: RowType) => emit('TABLE_DATA_VIEW_EVENT', {...row})

// 详情
const handleDetailFn = (row: RowType) => emit('TABLE_DATA_DETAIL_EVENT', {...row})

// 添加
const handleAddFn = () => emit('TABLE_DATA_ADD_EVENT')

// 编辑
const handleEditFn = (row: RowType) => emit('TABLE_DATA_EDIT_EVENT', {...row})

// 删除
const handleDeleteFn = (row: RowType) => {
	if(!row.isSelect) {
		return ElMessage({
			type: 'error',
			message: '请先勾选要删除的项目'
		})
	}
	const isMultipleDeletetFlag = false
	emit('TABLE_DATA_DELETE_EVENT', row, isMultipleDeletetFlag) 
}

// 翻页
const updateCurrentPageDataFn = () => emit('TABLE_DATA_UPDATE_EVENT')

// 流控页面匹配策略字段自适应宽度
type FiltersType = {
	k: string
	v: string
}
const getFiltersWidthFn = (data: RowsType, pl = 0, pr = 0): number => {
	const font = `14px ${FONTS}`
	const itemWidthArr: number[] = []
	data.forEach(item => {
		const f: FiltersType[] = item.filters
		const len = f?.length ?? 0
		const fn = (i: number): number => {
			let arr = f[i]?.v?.split(',')
			let w = 0
			arr.forEach(itemInner => w += Utils.getStringTextWidth(itemInner, font) + 2 * 5 + 3)
			return w + 2
		}

		if(len) {
			let itemWidth = 0
			const t_p_w = 50
			for(let i = 0; i < len; i++) {
				const isSplitFlag = f[i]?.v?.includes(',')
				const k_w = Utils.getStringTextWidth(f[i].k, font)
				const v_w = isSplitFlag ? fn(i) : Utils.getStringTextWidth(f[i].v, font)
				const p_w = 2 * (pl + pr)
				const m_w = 10
				itemWidth += Utils_Math.add(v_w, k_w) + p_w + m_w
			}
			itemWidthArr.push(Utils_Math.roundFormat(itemWidth, 0) - 10 + t_p_w)
		}
	})
	if(itemWidthArr?.length) {
		return Math.max(...itemWidthArr)
	}
	return 0
}

const setStringTextColumnAutoWidthFn = (data: RowsType, column: TableHeaderColumnsItemType) => {
	const font = `14px ${FONTS}`
	const columnStrArr = [column.label]
	const itemWidthArr = []
	const t_p_w = 26
	data.forEach(item => {
		const columnStr = item[column.prop] + ''
		columnStr?.length && columnStrArr.push(columnStr)
	})
	columnStrArr.forEach(item => itemWidthArr.push(Utils_Math.roundFormat(Utils.getStringTextWidth(item, font) + t_p_w, 0)))
	itemWidthArr[0] = Utils_Math.roundFormat(Utils.getStringTextWidth(column.label, `bold ${font}`) + t_p_w, 0)
	// 如果表格列设置排序，加上排序图标的宽度
	if(column.isHeaderSolt) itemWidthArr[0] += 15
	if(itemWidthArr?.length) return Math.max(...itemWidthArr)
	return 0
}

const setAutoWidthFn = (item: TableHeaderColumnsItemType) => {
	const data = tableData.value.data
	const len = data.length
	if(item.prop === 'filters') return getFiltersWidthFn(data, 5, 5)
	if(len) return setStringTextColumnAutoWidthFn(data, item)
	return 0
}

const multipleSelectTipFn = (tipTxt = '删除') => {
	if(!mainParams.selectRows.length) {
		ElMessage.error(`请先勾选要${tipTxt}的数据`)
		return false
	}
	return true
}
// 批量操作删除
const handleMultipleDeleteFn = () => {
	if(!multipleSelectTipFn()) return
	$mitt.emit('TABLE_MULTIPLE_DELETE_EVENT', mainParams.selectRows)
}
// 批量启用
const handleMultipleSwitchOnFn = () => {
	if(!multipleSelectTipFn(SWITCH_ON_TEXT)) return

	const isAllowFlag = mainParams.selectRows.every(item => item.is_enable)
	if(isAllowFlag) return ElMessage.info('操作无效！当前所有选中的选项已是启用状态')

	// 如果所有选项本身都是启用状态，取消操作
	const title = `批量${SWITCH_ON_TEXT}`
	const isSwitchOnFlag = true
	const multipleParams = {rows: mainParams.selectRows, title, isSwitchOnFlag}
	$mitt.emit('TABLE_MULTIPLE_SWITCH_EVENT', multipleParams)
}
// 批量禁用
const handleMultipleSwitchOffFn = () => {
	if(!multipleSelectTipFn(SWITCH_OFF_TEXT)) return

	// 如果所有选项本身都是禁用状态，取消操作
	const isAllowFlag = mainParams.selectRows.every(item => !item.is_enable)
	if(isAllowFlag) return ElMessage.info('操作无效！当前所有选中的选项已是禁用状态')

	const title = `批量${SWITCH_OFF_TEXT}`
	const isSwitchOnFlag = false
	$mitt.emit('TABLE_MULTIPLE_SWITCH_EVENT', {rows: mainParams.selectRows, title, isSwitchOnFlag})
}

defineExpose({
	
})

onMounted(() => {
	// 批量删除
	$mitt.on('MULTIPLE_DELETE_EVENT', () => handleMultipleDeleteFn())
	// 批量启用
	$mitt.on('MULTIPLE_SWITCH_ON_EVENT', () => handleMultipleSwitchOnFn())
	// 批量禁用
	$mitt.on('MULTIPLE_SWITCH_OFF_EVENT', () => handleMultipleSwitchOffFn())
})
onBeforeUnmount(() => {
	$mitt.all.delete('MULTIPLE_DELETE_EVENT')
	$mitt.all.delete('MULTIPLE_SWITCH_ON_EVENT')
	$mitt.all.delete('MULTIPLE_SWITCH_OFF_EVENT')
})
</script>

<template>
	<el-form class="table-bar">
		<el-table 
			:data="tableData.data" 
			highlight-current-row 
			border 
			:style="{width: `${tableData.width ? tableData.width : '100%'}`}" 
			:max-height="`${tableData.tableMaxHeight + 20}`" 
			@selection-change="handleSelectionChange" 
			:class="`mb-${tableData.tableMb}`" 
			empty-text="暂无数据" 
		>
			<el-table-column v-if="tableData.operationConfig?.isShowFlag" type="selection" width="58" align="center"></el-table-column>
			<el-table-column 
				v-if="tableData.serialNumberShowFlag" 
				type="index" 
				:index="serialIndexFn" 
				label="序号" 
				:width="tableData.serialWidth ? tableData.serialWidth : 70" 
				align="center" 
			 />

			<el-table-column 
				v-for="(item, index) in tableHeaderColumns" 
				:key="`edit_${index}`" 
				:sortable="item.isSort ? true : false" 
				:prop="item.prop" 
				:label="item.label" 
				:fixed="item.fixed ? item.fixed : false" 
				:min-width="item.width ? item.width : setAutoWidthFn(item)" 
				:align="item.align ? item.align : 'auto'" 
			>
				<template #header="{ column }">
					<template v-if="item.isHeaderSlot">
						<slot :name="item.porp" :column="{column, item}" />
					</template>

					<template v-else>
						{{ item.label }}
					</template>
				</template>
				<template #default="scope">
					<div :class="[`${tableData.lineHeightFlag ? 'pt-5 pb-5' : ''}`]">
						<!-- 使用插槽 -->
						<template v-if="item.isSlot">
							<!-- 默认slotScope未false, 插槽内容对象为row -->
							<slot v-if="item.slotScope" :scope="scope" :name="item.slotName"></slot>
							<slot v-else :row="scope.row" :name="item.slotName"></slot>
						</template>

						<!-- 原数据，不使用插槽 -->
						<div
							v-else
							class="ellipsis"
							:title="Array.isArray(scope.row[item.prop]) ? '' : scope.row[item.prop]"
							:alt="Array.isArray(scope.row[item.prop]) ? '' : scope.row[item.prop]"
						>
							<!-- 超长-可复制 -->
							<el-tooltip
								v-if="scope.row[item.prop] && (typeof scope.row[item.prop] === 'string') && scope.row[item.prop].length > 50"
								effect="dark"
								placement="left"
							>
								<template #content>
									<el-button @click="COPY_TEXT_FN(scope.row[item.prop])">
										复制
									</el-button>
								</template>
								{{scope.row[item.prop]}}
							</el-tooltip>
							
							<!-- 常规，不带复制功能 -->
							<div v-else>
								<!-- 空值替换为“--” -->
								<template v-if="tableData.isReplaceSpaceFlag">
									{{
										(
											scope.row[item.prop] === ''
												|| scope.row[item.prop] === null
												|| scope.row[item.prop] === undefined
										) 
											? '--' 
											: scope.row[item.prop]
									}}
								</template>
								<!-- 不替换，显示原数据 -->
								<template v-else>
									{{scope.row[item.prop]}}
								</template>
							</div>
						</div>
					</div>
				</template>
			</el-table-column>

			<!-- 操作 -->
			<!-- 单个按钮 width = 78, 两个按钮 width = 145 -->
			<el-table-column 
				v-if="tableData.operationConfig?.isShowFlag ? true : false" 
				fixed="right" 
				:width="tableData.operationConfig?.width ? tableData.operationConfig.width : 210" 
			>
				<template #header>
					<div class="table-operation-bar">
						<template v-if="tableData.isMultipleOperationFlag">
							<slot><b>操作</b></slot>
						</template>
						<span v-else>
							<b>操作</b>
						</span>
					</div>
				</template>

				<template #default="scope">
					<div class="table-operation-bar">
						<el-button v-if="tableData.isPreviewFlag" type="primary" size="small" @click="handleViewFn(scope.row)" v-preventReClick>
							<el-icon><View /></el-icon>预览
						</el-button>
						<el-button v-if="tableData.isDetailFlag" type="primary" size="small" @click="handleDetailFn(scope.row)" v-preventReClick>
							<el-icon><View /></el-icon>详情
						</el-button>
						<el-button v-if="tableData.isEditFlag" type="success" size="small" @click="handleEditFn(scope.row)" v-auth v-preventReClick>
							<el-icon><Edit /></el-icon>编辑
						</el-button>
						<el-button v-if="tableData.isAddFlag" type="success" size="small" @click="handleAddFn" v-auth v-preventReClick>
							<el-icon><Edit /></el-icon>添加
						</el-button>
						<el-button v-if="tableData.isDeleteFlag" type="danger" size="small" @click="handleDeleteFn(scope.row)" v-auth v-preventReClick>
							<el-icon><Delete /></el-icon>删除
						</el-button>
					</div>
				</template>
			</el-table-column>
		</el-table>

		<!-- 分页 -->
		<pagination 
			v-if="!tableData.paginationHideFlag"
			@updateCurrentPageEvent="updateCurrentPageDataFn" 
			v-model:tableData="tableDataValue" 
		/>
	</el-form>
</template>

<style lang="scss" scoped>
.table-bar {
	:deep(.el-table) {
		thead .el-icon {
			margin-right: 0;
		}
		.el-button-bar {
			display: -webkit-flex;
			display: flex;
			justify-content: center;
			align-items: center;
			.el-button {
				width: auto;
				padding: .05rem;
			}
		}
		.table-icon {
			display: inline-block;
			width: .2rem;
			height: .2rem;
			line-height: .2rem;
			text-align: center;
			margin-bottom: -.05rem;
			border-radius: 50%;
			.el-icon {
				margin: -.04rem 0 0 0;
				vertical-align: middle;
				color: $color-white;
			}
		}

		th > .cell {
			color: #606266;
			font-weight: bold;
			.el-dropdown {
				height: .24rem;
				line-height: .24rem;
				span {
					font-weight: bold;
				}
			}

			.filter-key {
				position: absolute;
				left: .12rem;
				right: .12rem;
				top: .2rem;
				color: #999;
				font-size: .12rem;

				.item {
					max-width: 100%;
					height: .16rem;
					line-height: .16rem;
					padding: 0 .04rem;
					box-shadow: 0 0 0 .01rem #ddd inset;
					border-radius: .03rem;
				}
			}
		}
	}
}
</style>